package cn.yto.print.utils;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class FileLockUtil {

    private static final Logger logger = LogManager.getLogger(FileLockUtil.class);

    public static final String LOCK_FILE_PATH = "lock_file.lock";
    private static final Lock REENTRANT_LOCK = new ReentrantLock();
    private static FileLock fileLock;
    /** 文件通道 */
    private static FileChannel fileChannel;

    /**
     * 尝试获取程序文件锁
     */
    public static boolean getFileLock() {
        final String filePath = CommonUtil.getCurrentDir(LOCK_FILE_PATH);
        REENTRANT_LOCK.lock();
        try {
            File lockFile = new File(filePath);
            // 如果文件不存在，则先尝试创建
            if (!lockFile.exists()) {
                boolean created = lockFile.createNewFile();
                if (!created) {
                    logger.error("锁文件已存在或创建失败: {}", filePath);
                }
            }
            // 非阻塞方式尝试获取锁
            FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel();
            FileLock lock = channel.tryLock();
            if (lock == null) {
                return false;
            }
            fileLock = lock;
            fileChannel = channel;
        } catch (Exception e) {
            logger.error("获取程序文件锁异常", e);
            return false;
        } finally {
            REENTRANT_LOCK.unlock();
        }
        return true;
    }

    /**
     * 释放文件锁
     */
    public static void releaseLock() {
        REENTRANT_LOCK.lock();
        try {
            // 释放文件锁
            if (fileLock != null) {
                try {
                    fileLock.release();
                } catch (Exception e) {
                    logger.error("释放文件锁异常", e);
                } finally {
                    fileLock = null;
                }
            }
            // 关闭文件通道
            if (fileChannel != null) {
                try {
                    fileChannel.close();
                } catch (Exception e) {
                    logger.error("关闭文件通道异常", e);
                } finally {
                    fileChannel = null;
                }
            }
        } catch (Exception e) {
            logger.error("释放程序文件锁异常", e);
        } finally {
            REENTRANT_LOCK.unlock();
        }
    }

}
